package net.wanho.advice;

import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import net.wanho.R.R;
import net.wanho.dto.LoginDTO;
import net.wanho.po.LoginLog;
import net.wanho.service.LogService;
import net.wanho.util.AddressUtil;
import net.wanho.util.ServletUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 操作日志切面
 */
@Component
@Aspect
public class LoginLogAspect {
    // 注入登录日志服务
    @Resource
    private LogService loginLogService;

    // 定义切点,拦截登录接口
    @Pointcut("execution(* net.wanho.controller.LoginController.login(..))")
    public void pc() {
    }

    // 环绕通知,处理登录日志记录
    @Around("pc()")
    public Object around(ProceedingJoinPoint joinPoint) throws Exception {
        // 获取当前请求对象
        HttpServletRequest request = ServletUtil.getRequest();
        // 创建登录日志对象
        LoginLog loginLog = new LoginLog();
        // 获取登录用户信息
        LoginDTO loginUserDTO = (LoginDTO) joinPoint.getArgs()[0];
        // 设置用户名
        loginLog.setUserName(loginUserDTO.getUserCode());
        // 设置IP地址
        loginLog.setIpaddr(AddressUtil.getIpAddr(request));
        // 设置登录地点
        loginLog.setLoginLocation(AddressUtil.getLocationByIp(loginLog.getIpaddr()));
        // 获取User-Agent
        String UserAgent = request.getHeader("User-Agent");
        // 解析User-Agent信息
        UserAgent agent = UserAgentUtil.parse(UserAgent);
        // 设置浏览器信息
        loginLog.setBrowser(agent.getBrowser().getName());
        // 设置操作系统信息
        loginLog.setOs(agent.getOs().getName());
        // 设置登录时间
        loginLog.setLoginTime(new Date());
        try {
            // 执行目标方法
            R result = (R) joinPoint.proceed();
            // 设置登录状态为成功
            loginLog.setStatus("0");
            // 设置成功消息
            loginLog.setMsg(result.getMessage());
            return result;
        } catch (Throwable e) {
            // 处理异常信息
            String msg = e.getMessage().replaceAll("^[a-zA-Z.]+\\:", "");
            // 设置登录状态为失败
            loginLog.setStatus("1");
            // 设置失败消息
            loginLog.setMsg(msg);
            // 抛出登录异常
            throw new Exception(msg);
        } finally {
            // 保存登录日志
            loginLogService.add(loginLog);
        }
    }

}